import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import sqlite3
from datetime import datetime
import csv

DB_NAME = 'vip_system.db'

def center_window(win, width=300, height=180):
    screen_width = win.winfo_screenwidth()
    screen_height = win.winfo_screenheight()
    x = (screen_width - width) // 2
    y = (screen_height - height) // 2
    win.geometry(f"{width}x{height}+{x}+{y}")

class VIPApp:
    def __init__(self, root):
        self.root = root
        self.root.title("理发店会员管理系统")
        self.root.attributes('-fullscreen', True)

        self.conn = sqlite3.connect(DB_NAME)
        self.create_tables()

        self.build_main_ui()

    def create_tables(self):
        cursor = self.conn.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT,
                phone TEXT UNIQUE,
                balance REAL DEFAULT 0
            )
        ''')
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS records (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                type TEXT,
                amount REAL,
                timestamp TEXT,
                FOREIGN KEY(user_id) REFERENCES users(id)
            )
        ''')
        self.conn.commit()
    def on_closing(self):
        try:
            if hasattr(self, "conn"):
                self.conn.close()
        except Exception as e:
            print("关闭数据库失败：", e)
        self.root.destroy()

    def build_main_ui(self):
        # 顶部功能区
        top_frame = tk.Frame(self.root)
        top_frame.pack(side=tk.TOP, fill=tk.X, pady=5)

        add_btn = tk.Button(top_frame, text="添加会员", command=self.add_user_window, width=12)
        add_btn.pack(side=tk.LEFT, padx=5)

        export_btn = tk.Button(top_frame, text="导出会员信息", command=self.export_users, width=12)
        export_btn.pack(side=tk.LEFT, padx=5)

        stat_btn = tk.Button(top_frame, text="统计总金额", command=self.show_total_balance, width=12)
        stat_btn.pack(side=tk.LEFT, padx=5)

        exit_btn = tk.Button(top_frame, text="退出系统", command=self.on_closing, width=12, fg='red')
        exit_btn.pack(side=tk.RIGHT, padx=10)

        toggle_fullscreen_btn = tk.Button(top_frame, text="退出全屏", command=self.toggle_fullscreen, width=12)
        toggle_fullscreen_btn.pack(side=tk.RIGHT, padx=5)

        maximize_btn = tk.Button(top_frame, text="进入全屏", command=self.enter_fullscreen, width=12)
        maximize_btn.pack(side=tk.RIGHT, padx=5)
 

        # 消费/充值区
        op_frame = tk.LabelFrame(self.root, text="充值/消费")
        op_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=5)

        tk.Label(op_frame, text="手机号尾号:").grid(row=0, column=0, padx=5, pady=5)
        self.search_var = tk.StringVar()
        self.tail_entry = tk.Entry(op_frame, textvariable=self.search_var)
        self.tail_entry.grid(row=0, column=1, padx=5, pady=5)
        self.tail_entry.bind('<Return>', lambda e: self.search_by_tail())

        search_btn = tk.Button(op_frame, text="查询会员", command=self.search_by_tail, width=10)
        search_btn.grid(row=0, column=2, padx=5)

        self.user_info_var = tk.StringVar()
        tk.Label(op_frame, textvariable=self.user_info_var, fg="blue").grid(row=1, column=0, columnspan=3, pady=5)

        tk.Label(op_frame, text="金额:").grid(row=2, column=0, padx=5, pady=5)
        self.amount_entry = tk.Entry(op_frame)
        self.amount_entry.grid(row=2, column=1, padx=5, pady=5)

        charge_btn = tk.Button(op_frame, text="充值", command=self.charge_user, width=10)
        charge_btn.grid(row=2, column=2, padx=5)

        consume_btn = tk.Button(op_frame, text="消费", command=self.consume_user, width=10)
        consume_btn.grid(row=3, column=2, padx=5, pady=5)


        delete_btn = tk.Button(top_frame, text="删除会员", command=self.delete_user, width=12)
        delete_btn.pack(side=tk.LEFT, padx=5)

        # 会员列表
        list_frame = tk.LabelFrame(self.root, text="会员列表（点击会员查看消费记录）")
        list_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        columns = ("ID", "姓名", "手机号", "金额")
        self.tree = ttk.Treeview(list_frame, columns=columns, show='headings')
        for col in columns:
            self.tree.heading(col, text={"ID":"编号", "姓名":"姓名", "手机号":"手机号", "金额":"金额"}[col])
            self.tree.column(col, anchor='center')
        self.tree.pack(fill=tk.BOTH, expand=True)

        self.tree.bind("<Double-1>", self.on_member_double_click)
        self.tree.bind("<ButtonRelease-1>", self.on_tree_click)

        self.refresh_users()

    def enter_fullscreen(self):
        self.root.attributes('-fullscreen', True)
    def toggle_fullscreen(self):
        self.root.attributes('-fullscreen', False)
        width, height = 1371, 830
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        x = (screen_width - width) // 2
        y = (screen_height - height) // 2
        self.root.geometry(f"{width}x{height}+{x}+{y}")
    
 


        
    def on_tree_click(self, event):
        selected = self.tree.selection()
        if selected:
            item = self.tree.item(selected[0])
            phone = item["values"][2]  # 第三列是手机号
            tail = str(phone)[-4:] if len(str(phone)) >= 4 else str(phone)
            self.search_var.set(tail)
            self.search_by_tail()  # 调用已有的搜索函数，自动填入会员信息
    def delete_user(self):
        selected = self.tree.selection()
        if not selected:
            messagebox.showwarning("提示", "请先选择要删除的会员")
            return

        user_info = self.tree.item(selected[0], "values")
        user_id, name = user_info[0], user_info[1]


        if self.tree.item(selected[0], "values")[3] != "0.0":
            messagebox.showwarning("提示", "请先清空会员余额")
            return

        confirm = messagebox.askyesno("确认删除", f"确定要删除会员「{name}」及其所有记录吗？此操作不可恢复。")
        if not confirm:
            return

        cursor = self.conn.cursor()
        cursor.execute("DELETE FROM records WHERE user_id=?", (user_id,))
        cursor.execute("DELETE FROM users WHERE id=?", (user_id,))
        self.conn.commit()

        messagebox.showinfo("成功", f"已删除会员「{name}」及其所有记录")
        self.refresh_users()
    def refresh_users(self):
        for i in self.tree.get_children():
            self.tree.delete(i)
        cursor = self.conn.cursor()
        cursor.execute("SELECT id, name, phone, balance FROM users ORDER BY id")
        for row in cursor.fetchall():
            self.tree.insert("", "end", values=(row[0], row[1], row[2], f"{row[3]:.1f}"))
        self.user_info_var.set("")
        self.amount_entry.delete(0, tk.END)
        self.tail_entry.delete(0, tk.END)
        if hasattr(self, 'current_user'):
            del self.current_user

    def refresh_usersxf(self):
        # 清空表格
        for i in self.tree.get_children():
            self.tree.delete(i)

        # 重新读取数据库并填充表格
        cursor = self.conn.cursor()
        cursor.execute("SELECT id, name, phone, balance FROM users ORDER BY id")
        for row in cursor.fetchall():
            self.tree.insert("", "end", values=(row[0], row[1], row[2], f"{row[3]:.1f}"))

        # 保留 tail_entry 不清除
        self.amount_entry.delete(0, tk.END)  # 清空金额输入框
        self.user_info_var.set("")           # 清空显示标签
        if hasattr(self, 'current_user'):
            del self.current_user            # 清空当前选中的会员
        self.search_by_tail()

    def add_user_window(self):
        win = tk.Toplevel(self.root)
        win.title("添加会员")
        center_window(win, 350, 180)
        win.grab_set()

        frame = tk.Frame(win)
        frame.pack(padx=20, pady=20, fill='both', expand=True)

        tk.Label(frame, text="姓名:").grid(row=0, column=0, sticky="e", pady=5)
        name_entry = tk.Entry(frame)
        name_entry.grid(row=0, column=1, pady=5)

        tk.Label(frame, text="手机号:").grid(row=1, column=0, sticky="e", pady=5)
        phone_entry = tk.Entry(frame)
        phone_entry.grid(row=1, column=1, pady=5)

        def save():
            name = name_entry.get().strip()
            phone = phone_entry.get().strip()
            if not name or not phone:
                messagebox.showerror("错误", "姓名和手机号不能为空")
                return
            cursor = self.conn.cursor()
            try:
                cursor.execute("INSERT INTO users (name, phone) VALUES (?, ?)", (name, phone))
                self.conn.commit()
            except sqlite3.IntegrityError:
                messagebox.showerror("错误", "手机号已存在")
                return
            win.destroy()
            self.refresh_users()

        btn_frame = tk.Frame(win)
        btn_frame.pack(pady=10)

        tk.Button(btn_frame, text="添加", command=save, width=10).pack(side="left", padx=5)
        tk.Button(btn_frame, text="取消", command=win.destroy, width=10).pack(side="right", padx=5)

    def search_by_tail(self):
        tail = self.tail_entry.get().strip()
        if not tail:
            messagebox.showerror("错误", "请输入手机号尾号")
            return
        cursor = self.conn.cursor()
        cursor.execute("SELECT id, name, phone, balance FROM users WHERE phone LIKE ?", ('%' + tail,))
        results = cursor.fetchall()
        if not results:
            messagebox.showinfo("提示", "没有找到匹配的会员")
            self.user_info_var.set("")
            return
        elif len(results) == 1:
            self.current_user = results[0]
            self.user_info_var.set(f"当前会员：{results[0][1]}，手机号：{results[0][2]}，余额：{results[0][3]:.1f}")
        else:
            self.choose_user_window(results)

    def choose_user_window(self, users):
        win = tk.Toplevel(self.root)
        win.title("选择会员")
        center_window(win, 400, 250)
        win.grab_set()

        tk.Label(win, text="找到多个会员，请选择：").pack(pady=5)

        listbox = tk.Listbox(win, width=50, height=8)
        for u in users:
            listbox.insert(tk.END, f"{u[1]} - {u[2]} - 余额：{u[3]:.1f}")
        listbox.pack(padx=10, pady=10)

        def select():
            idx = listbox.curselection()
            if not idx:
                messagebox.showerror("错误", "请先选择会员")
                return
            self.current_user = users[idx[0]]
            self.user_info_var.set(f"当前会员：{self.current_user[1]}，手机号：{self.current_user[2]}，余额：{self.current_user[3]:.1f}")
            win.destroy()

        btn_frame = tk.Frame(win)
        btn_frame.pack(pady=10)
        tk.Button(btn_frame, text="确定", command=select, width=10).pack(side=tk.LEFT, padx=5)
        tk.Button(btn_frame, text="取消", command=win.destroy, width=10).pack(side=tk.RIGHT, padx=5)

    def charge_user(self):
        if not hasattr(self, 'current_user'):
            messagebox.showerror("错误", "请先查询并选择会员")
            return
        try:
            amount = float(self.amount_entry.get())
        except:
            messagebox.showerror("错误", "请输入正确金额")
            return
        if amount <= 0:
            messagebox.showerror("错误", "金额必须大于0")
            return

        new_balance = self.current_user[3] + amount
        cursor = self.conn.cursor()
        cursor.execute("UPDATE users SET balance=? WHERE id=?", (new_balance, self.current_user[0]))
        cursor.execute("INSERT INTO records (user_id, type, amount, timestamp) VALUES (?, '充值', ?, ?)",
                       (self.current_user[0], amount, datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
        self.conn.commit()
        messagebox.showinfo("成功", f"充值成功，当前余额：{new_balance:.1f}")
        self.refresh_usersxf()
        # self.amount_entry.delete(0, tk.END)

    def consume_user(self):
        if not hasattr(self, 'current_user'):
            messagebox.showerror("错误", "请先查询并选择会员")
            return
        try:
            amount = float(self.amount_entry.get())
        except:
            messagebox.showerror("错误", "请输入正确金额")
            return
        if amount <= 0:
            messagebox.showerror("错误", "金额必须大于0")
            return
        if amount > self.current_user[3]:
            messagebox.showerror("错误", "余额不足")
            return

        new_balance = self.current_user[3] - amount
        cursor = self.conn.cursor()
        cursor.execute("UPDATE users SET balance=? WHERE id=?", (new_balance, self.current_user[0]))
        cursor.execute("INSERT INTO records (user_id, type, amount, timestamp) VALUES (?, '消费', ?, ?)",
                       (self.current_user[0], amount, datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
        self.conn.commit()
        messagebox.showinfo("成功", f"消费成功，当前余额：{new_balance:.1f}")
        self.refresh_usersxf()
        # self.amount_entry.delete(0, tk.END)

    def export_users(self):
        filename = filedialog.asksaveasfilename(defaultextension=".csv",
                                                filetypes=[("CSV文件", "*.csv")])
        if not filename:
            return
        cursor = self.conn.cursor()
        cursor.execute("SELECT name, phone, balance FROM users ORDER BY id")
        rows = cursor.fetchall()
        try:
            with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
                writer = csv.writer(f)
                writer.writerow(["姓名", "手机号", "金额"])
                writer.writerows(rows)
            messagebox.showinfo("导出成功", f"会员信息已导出到：{filename}")
        except Exception as e:
            messagebox.showerror("导出失败", str(e))

    def show_total_balance(self):
        cursor = self.conn.cursor()
        cursor.execute("SELECT SUM(balance) FROM users")
        total = cursor.fetchone()[0]
        total = total if total else 0
        messagebox.showinfo("统计", f"所有会员余额总计：{total:.1f}")

    def on_member_double_click(self, event):
        item = self.tree.selection()
        if not item:
            return
        user_id = self.tree.item(item, "values")[0]
        self.show_records(user_id)

    def show_records(self, user_id):
        win = tk.Toplevel(self.root)
        win.title("消费/充值记录")
        center_window(win, 700, 400)
        win.grab_set()

        cols = ("类型", "金额", "时间")
        tree = ttk.Treeview(win, columns=cols, show='headings')
        for col in cols:
            tree.heading(col, text=col)
            tree.column(col, anchor='center')
        tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        cursor = self.conn.cursor()
        cursor.execute("SELECT type, amount, timestamp FROM records WHERE user_id=? ORDER BY timestamp DESC", (user_id,))
        for r in cursor.fetchall():
            tree.insert("", "end", values=(r[0], f"{r[1]:.1f}", r[2]))

class LoginWindow:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("管理员登录")
        center_window(self.root, 300, 180)
        self.root.resizable(False, False)

        frame = tk.Frame(self.root)
        frame.pack(padx=20, pady=20)

        tk.Label(frame, text="用户名:").grid(row=0, column=0, pady=10)
        self.username_entry = tk.Entry(frame)
        self.username_entry.grid(row=0, column=1, pady=10)
        self.username_entry.bind('<Return>', lambda e: self.try_login())

        tk.Label(frame, text="密码:").grid(row=1, column=0, pady=10)
        self.password_entry = tk.Entry(frame, show="*")
        self.password_entry.grid(row=1, column=1, pady=10)
        self.password_entry.bind('<Return>', lambda e: self.try_login())

        login_btn = tk.Button(frame, text="登录", width=10, command=self.try_login)
        login_btn.grid(row=2, column=0, columnspan=2, pady=10)

        self.root.mainloop()

    def try_login(self):
        username = self.username_entry.get().strip()
        password = self.password_entry.get().strip()
        if username == "admin" and password == "zyp123":
            self.root.destroy()
            main_root = tk.Tk()
            app = VIPApp(main_root)
            main_root.mainloop()
        else:
            messagebox.showerror("登录失败", "用户名或密码错误")

if __name__ == "__main__":
    LoginWindow()
